package cn.bytets.rpc.api.balance;

import cn.bytets.rpc.api.invoke.Invocation;
import cn.bytets.rpc.api.invoke.Invoker;
import cn.bytets.rpc.common.URL;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 这里保存RPC一些调用状态,例如: 服务调用次数,成功次数,失败次数,总调用次数
 */
public class RpcStatus {
    /**
     * key : 服务器地址
     */
    private static final ConcurrentMap<String, ConcurrentMap<String, RpcStatus>>
            METHOD_STATISTICS = new ConcurrentHashMap<String, ConcurrentMap<String, RpcStatus>>();

    private static final ConcurrentMap<String, RpcStatus> SERVICE_STATISTICS = new ConcurrentHashMap<String, RpcStatus>();

    private final AtomicInteger active = new AtomicInteger();

    private RpcStatus(){}

    public static RpcStatus getStatus(URL url) {
        String uri = url.toIdentityString();
        RpcStatus status = SERVICE_STATISTICS.get(uri);
        if (status == null) {
            SERVICE_STATISTICS.putIfAbsent(uri, new RpcStatus());
            status = SERVICE_STATISTICS.get(uri);
        }
        return status;
    }
    public static void removeStatus(URL url) {
        String uri = url.toIdentityString();
        SERVICE_STATISTICS.remove(uri);
    }
    /**
     * @param url
     * @param methodName
     * @return status
     */
    public static RpcStatus getStatus(URL url, String methodName) {
        String uri = url.toIdentityString();
        ConcurrentMap<String, RpcStatus> map = METHOD_STATISTICS.get(uri);
        if (map == null) {
            METHOD_STATISTICS.putIfAbsent(uri, new ConcurrentHashMap<String, RpcStatus>());
            map = METHOD_STATISTICS.get(uri);
        }
        RpcStatus status = map.get(methodName);
        if (status == null) {
            map.putIfAbsent(methodName, new RpcStatus());
            status = map.get(methodName);
        }
        return status;
    }
    public static int getActive(Invoker invoker, Invocation invocation){
        return getStatus(invoker.getUrl(),invocation.getMethodName()).getActive();
    }
    /**
     * @param url
     */
    public static void removeStatus(URL url, String methodName) {
        String uri = url.toIdentityString();
        ConcurrentMap<String, RpcStatus> map = METHOD_STATISTICS.get(uri);
        if (map != null) {
            map.remove(methodName);
        }
    }
    public int getActive() {
        return active.get();
    }
    public void addActive(){
        active.incrementAndGet();
    }
}
